package com.ztstkj.lzscale.ui

import android.annotation.SuppressLint
import android.os.Bundle
import androidx.lifecycle.lifecycleScope
import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.DeviceUtils
import com.blankj.utilcode.util.GsonUtils
import com.proembed.service.MyService
import com.sscl.baselibrary.utils.DebugUtil
import com.ztstkj.lzscale.fragments.NavFragment
import com.ztstkj.lzscale.fragments.UserFragment
import com.ztstkj.lzservices.cameras.savePath
import com.ztstkj.lzservices.dto.HeartInput
import com.ztstkj.lzservices.dto.UserOutput
import com.ztstkj.lzservices.events.EventCard
import com.ztstkj.lzservices.events.EventCategory
import com.ztstkj.lzservices.events.EventRate
import com.ztstkj.lzservices.events.EventWeight
import com.ztstkj.lzservices.exceptions.LogConstant
import com.ztstkj.lzservices.exceptions.apiCall
import com.ztstkj.lzservices.extension.ExceptionExt.toStackTraceString
import com.ztstkj.lzservices.mmkvs.MmkvManager
import com.ztstkj.lzservices.model.SysSetting
import com.ztstkj.lzservices.networks.DowloadManager
import com.ztstkj.lzservices.networks.NetworkUtils
import com.ztstkj.lzservices.retrofits.Api
import com.ztstkj.lzservices.serialports.ModbusData
import com.ztstkj.lzservices.serialports.ModbusError
import com.ztstkj.lzservices.serialports.SerialPortUtil
import com.ztstkj.lzservices.utils.SpeakUtil
import com.ztstkj.lzservices.utils.UrlUtil
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.io.File
import java.util.Timer
import java.util.TimerTask
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.TimeUnit

open class ScaleActivity : BaseActivity() {

    protected var curEquipmentId: Long = 0
    protected var curDeptId: Int = 0
    protected var curUserId: Long = 0
    protected var curCard: String = ""
    protected var curUser: UserOutput?=null
    protected var curWeight: Int = 0
    protected var curPhotoBase64: String = ""
    protected var curPhotoPath: String = ""
    protected lateinit var curSetting:SysSetting
    private  lateinit var resetCurUserTimer:Timer
    private var schedulerOne: ScheduledExecutorService? = null
    private var schedulerFive: ScheduledExecutorService? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        curSetting=MmkvManager.getSysSetting()
        EventBus.getDefault().register(this)
        updateUserFragment(UserFragment(null))
        updateNavFragment(NavFragment())
        initMyService()
        initScheduledOne()
        initScheduledFive()
        resetCurUser()
    }

    /**
     * 60秒无操作退出当前用户
     */
    private fun resetCurUser(){
        resetCurUserTimer=Timer()
        resetCurUserTimer.schedule(object : TimerTask() {
            override fun run() {
                DebugUtil.debugOut("60秒无操作退出用户")
                curUser=null
                curUserId=0
                curCard=""
                updateUserFragment(UserFragment(null))
            }

        },60*1000)
    }
    private fun initMyService() {
        mXService = MyService(this)
        mXService?.setAppListen(AppUtils.getAppPackageName(), 60) //60秒保活
        mXService?.appBoot=AppUtils.getAppPackageName()
        mXService?.hideNavBar =true
    }
    private fun initScheduledOne() {
        schedulerOne = Executors.newScheduledThreadPool(1)
        schedulerOne?.scheduleWithFixedDelay({
            DebugUtil.debugOut("一分钟执行一次")
            DebugUtil.debugOut("待上传记录：${MmkvManager.getDeliveryCount()}")
            if (NetworkUtils.onLine) {
                taskUpload()
                taskUploadLog()
            }

        }, 15, 60, TimeUnit.SECONDS)
    }
    // 当前activity 需要上传的操作
    open fun taskUpload(){}

    private fun initScheduledFive() {
        schedulerOne = Executors.newScheduledThreadPool(1)
        schedulerOne?.scheduleWithFixedDelay({
            DebugUtil.debugOut("五分钟执行一次")

            if (NetworkUtils.onLine) {
                taskHeart()
                delDiscardImg()
            }
        }, 10, 5 * 60, TimeUnit.SECONDS)
    }
    private  fun delDiscardImg(){
        val directory = File(savePath)
        if (directory.exists() && directory.isDirectory) {
            val files = directory.listFiles { file ->
                file.isFile && file.extension == "jpg" // 可以添加更多图片格式
            }
            if(files==null) return
            val deliveryImages=MmkvManager.getDeliveryImages()
            for (img in files){
                DebugUtil.debugOut(img.absolutePath)
                DebugUtil.debugOut(img.path)
               if(deliveryImages.contains(img.absolutePath))
                   continue
                else
                    img.delete()
            }

        }
    }
    //心跳检查
    private fun taskHeart() {
        lifecycleScope.launch {
            val heartInput = HeartInput(DeviceUtils.getAndroidID(), AppUtils.getAppVersionName())
            val resp = apiCall { Api.get().postHeart(heartInput) }
            if (resp.success && resp.data != null) {
                //是否启动日志记载
                MmkvManager.enableLog = resp.data?.enableLog == true
                if(!MmkvManager.enableLog)
                    MmkvManager.removeAll()
                //有新版本下载新版
                if (resp.data!!.enableUpdate) {
                    val lastVersionCode = resp.data?.apkVersion?.toInt() ?: 0
                    DebugUtil.debugOut("自动更新：${resp.data!!.enableUpdate}，${lastVersionCode}>${AppUtils.getAppVersionCode()}")
                    if (lastVersionCode > AppUtils.getAppVersionCode()) {
                        downloadApp(resp.data?.downloadUrl ?: "")
                    }
                } else {
                    DebugUtil.debugOut("更新：未启用")
                }
            }
        }
    }

    private fun taskUploadLog() {
        val logs = MmkvManager.getTopLog()
        if (logs == null) {
            DebugUtil.debugOut("待上传日志：0，日志启用：${MmkvManager.enableLog}")
            return
        }
        lifecycleScope.launch {
            val resp = apiCall { Api.get().postLog(logs) }
            if (resp.success) {
                MmkvManager.removeLog(logs.map { log -> log.createtime.toString() })
                taskUploadLog()
            }else{
                MmkvManager.removeLog(logs.map { log -> log.createtime.toString() })
                taskUploadLog()
            }
        }
    }
    private fun downloadApp(url: String) {
        if (url.isEmpty()) return
        MmkvManager.addLog(LogConstant.APPDOWN, "开始下载")
        val filePath =
            "${baseContext.externalCacheDir!!.absolutePath}/${UrlUtil.getUriFileName(url)}"
        if (File(filePath).exists()) {
            MmkvManager.addLog(LogConstant.APPDOWN, "本地有文件，开始安装，path=${filePath}")
            installApkXc(filePath)

        } else {
            MmkvManager.addLog(LogConstant.APPDOWN, "本地没有文件，开始下载，path=${filePath}")
            lifecycleScope.launch {
                var processNum = 0
                DowloadManager.download(url, filePath, onProcess = { _, _, process ->
                    val processInt = (process * 100).toInt()
                    if (processInt % 10 == 0 && processNum != processInt) {
                        processNum = processInt
                        MmkvManager.addLog(LogConstant.APPDOWN, "process =$processInt%")
                    }
                }, onSuccess = {
                    MmkvManager.addLog(LogConstant.APPDOWN, "下载成功,地址：$filePath")
                    installApkXc(filePath)
                }, onError = {
                    it.printStackTrace()
                    MmkvManager.addLog(LogConstant.APPDOWN, "下载失败\r\n${it.toStackTraceString()}")
                })
            }
        }
    }

    //系能
    private fun installApkXc(filePath: String) {
        DebugUtil.warnOut("安装：installApkXc")
        mXService!!.silentInstallApk(filePath, packageName, true)
    }

    @SuppressLint("SetTextI18n")
    protected fun getUserByCardFromMkv(cardNo: String,modbus: ModbusData) {
        val user = MmkvManager.getCardQrcode(cardNo)
        if (user == null) {
            SerialPortUtil.writeS4(modbus.error(ModbusError.NOT_FOUND_CARD))
            SpeakUtil.speech(this, "无法识别卡号")
            return
        }
        DebugUtil.debugOut("识别到卡号：${GsonUtils.toJson(user)}")
        curUserId = user.userId
        curCard = cardNo
        user.cardNo= cardNo
        SerialPortUtil.writeS4(modbus.success())
        updateUserFragment(UserFragment(UserOutput(user.userId,
            user.cardNo,user.userName,user.userName,"",user.address,user.totalPoint,user.avatar)))
    }

    protected fun getUserByCard(cardNo: String,modbus: ModbusData) {
        lifecycleScope.launch {
            val resp = apiCall { Api.get().getUserForApp(DeviceUtils.getAndroidID(),cardNo) }
            val user = resp.data
            if (resp.success && user != null) {
                curUser=user
                curUserId = user.id
                curCard = cardNo
                user.cardNo= cardNo
                SerialPortUtil.writeS4(modbus.success())
                SpeakUtil.speech(applicationContext , "刷卡成功")
                updateUserFragment(UserFragment(user))
            } else {
                SerialPortUtil.writeS4(modbus.error(ModbusError.NOT_FOUND_CARD))
                SpeakUtil.speech(applicationContext, "无法识别卡号")
            }
        }
    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    protected fun onEventCardScale(e: EventCard) {}

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventCategoryScale(e: EventCategory) {}

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventWeightScale(e: EventWeight) {}

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventRateScale(e: EventRate) {}

    override fun onDestroy() {
        super.onDestroy()
        EventBus.getDefault().unregister(this)
        SpeakUtil.shutdown()
        schedulerOne?.shutdown()
        schedulerFive?.shutdown()
    }

    override fun onUserInteraction() {
        super.onUserInteraction()
        resetCurUser()
    }
}